import os
import time
from urllib.parse import urlparse
from PyQt5.QtWidgets import (
    QApplication, QMainWindow, QWidget, QTabWidget, QLabel, QLineEdit, QPushButton, QRadioButton, QTextEdit,
    QTreeWidget, QTreeWidgetItem, QHeaderView, QProgressBar, QHBoxLayout, QVBoxLayout, QGroupBox,
    QFileDialog, QMessageBox, QButtonGroup
)
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer
from m3u8_pro.db_utils import TaskDB
from m3u8_pro.m3u8_parser import parse_m3u8, download_m3u8
from m3u8_pro.downloader import DownloadManager
import m3u8_pro.config as config

class DownloadStatusUpdater(QThread):
    update_signal = pyqtSignal()
    
    def __init__(self):
        super().__init__()
        self.active = True
        
    def run(self):
        while self.active:
            self.update_signal.emit()
            time.sleep(3)
            
    def stop(self):
        self.active = False

class M3U8DownloaderApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("M3U8视频下载工具")
        self.resize(800, 600)
        
        self.db = TaskDB(config.DB_NAME)
        self.download_manager = DownloadManager(self.db, max_workers=config.MAX_DOWNLOAD_THREADS)
        self.status_updater = DownloadStatusUpdater()
        self.status_updater.update_signal.connect(self.update_download_status)
        self.status_updater.start()
        
        self.init_ui()
        self.load_tasks()
        
    def init_ui(self):
        # 创建主TabWidget
        self.tab_widget = QTabWidget()
        self.setCentralWidget(self.tab_widget)
        
        # 创建任务选项卡
        self.create_task_tab()
        
        # 任务下载选项卡
        self.create_download_tab()
        
    def create_task_tab(self):
        """创建任务管理界面"""
        task_tab = QWidget()
        layout = QVBoxLayout(task_tab)
        
        # 来源选择部分
        source_group = QGroupBox("M3U8来源")
        source_layout = QVBoxLayout()
        self.source_type_group = QButtonGroup()
        
        url_rb = QRadioButton("URL")
        file_rb = QRadioButton("本地文件")
        url_rb.setChecked(True)
        
        self.source_type_group.addButton(url_rb, 1)
        self.source_type_group.addButton(file_rb, 2)
        self.source_type_group.buttonClicked.connect(self.update_ui)
        
        source_layout.addWidget(url_rb)
        source_layout.addWidget(file_rb)
        source_group.setLayout(source_layout)
        
        # URL/文件输入区域
        url_group = QGroupBox()
        url_layout = QVBoxLayout()
        self.url_entry = QLineEdit()
        self.browse_button = QPushButton("浏览...")
        self.browse_button.clicked.connect(self.browse_file)
        
        url_layout.addWidget(QLabel("URL或文件路径:"))
        h_layout = QHBoxLayout()
        h_layout.addWidget(self.url_entry)
        h_layout.addWidget(self.browse_button)
        url_layout.addLayout(h_layout)
        url_group.setLayout(url_layout)
        
        # 视频信息区域
        info_group = QGroupBox("视频信息")
        info_layout = QVBoxLayout()
        
        self.name_entry = QLineEdit()
        self.refer_entry = QLineEdit()
        self.path_entry = QLineEdit(os.getcwd())
        self.path_button = QPushButton("选择路径")
        self.path_button.clicked.connect(self.select_path)
        
        info_layout.addWidget(QLabel("视频名称:"))
        info_layout.addWidget(self.name_entry)
        info_layout.addWidget(QLabel("Referer:"))
        info_layout.addWidget(self.refer_entry)
        info_layout.addWidget(QLabel("保存路径:"))
        
        h_path_layout = QHBoxLayout()
        h_path_layout.addWidget(self.path_entry)
        h_path_layout.addWidget(self.path_button)
        info_layout.addLayout(h_path_layout)
        
        info_group.setLayout(info_layout)
        
        # 创建任务按钮
        self.create_button = QPushButton("创建任务")
        self.create_button.clicked.connect(self.create_task)
        
        # 日志区域
        log_group = QGroupBox("操作日志")
        log_layout = QVBoxLayout()
        self.task_log = QTextEdit()
        self.task_log.setReadOnly(True)
        log_layout.addWidget(self.task_log)
        log_group.setLayout(log_layout)
        
        # 添加到主布局
        layout.addWidget(source_group)
        layout.addWidget(url_group)
        layout.addWidget(info_group)
        layout.addWidget(self.create_button)
        layout.addWidget(log_group, 1)
        
        task_tab.setLayout(layout)
        self.tab_widget.addTab(task_tab, "创建任务")
        
    def create_download_tab(self):
        """创建下载管理界面"""
        download_tab = QWidget()
        layout = QVBoxLayout(download_tab)
        
        # 任务列表
        self.task_tree = QTreeWidget()
        self.task_tree.setHeaderLabels(["ID", "视频名称", "状态", "进度"])
        self.task_tree.header().setSectionResizeMode(QHeaderView.ResizeToContents)
        self.task_tree.header().setSectionResizeMode(1, QHeaderView.Stretch)
        
        # 修复：设置选择行为为整行选择
        self.task_tree.setSelectionBehavior(QTreeWidget.SelectRows)
        self.task_tree.setSelectionMode(QTreeWidget.SingleSelection)
        
        # 控制按钮
        btn_layout = QHBoxLayout()
        self.start_button = QPushButton("开始下载")
        self.pause_button = QPushButton("暂停下载")
        self.delete_button = QPushButton("删除任务")
        self.refresh_button = QPushButton("刷新列表")
        
        self.start_button.clicked.connect(self.start_download)
        self.pause_button.clicked.connect(self.pause_download)
        self.delete_button.clicked.connect(self.delete_task)
        self.refresh_button.clicked.connect(self.load_tasks)
        
        btn_layout.addWidget(self.start_button)
        btn_layout.addWidget(self.pause_button)
        btn_layout.addWidget(self.delete_button)
        btn_layout.addStretch(1)
        btn_layout.addWidget(self.refresh_button)
        
        # 进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setRange(0, 100)
        
        # 下载日志
        log_group = QGroupBox("下载日志")
        log_layout = QVBoxLayout()
        self.download_log = QTextEdit()
        self.download_log.setReadOnly(True)
        log_layout.addWidget(self.download_log)
        log_group.setLayout(log_layout)
        
        # 添加到主布局
        layout.addWidget(self.task_tree)
        layout.addLayout(btn_layout)
        layout.addWidget(self.progress_bar)
        layout.addWidget(log_group, 1)
        
        download_tab.setLayout(layout)
        self.tab_widget.addTab(download_tab, "任务下载")
        
    def update_ui(self):
        """根据选择类型更新UI界面"""
        if self.source_type_group.checkedId() == 2:  # 本地文件选项
            self.browse_button.setEnabled(True)
        else:
            self.browse_button.setEnabled(True)
            
    def browse_file(self):
        """打开文件选择对话框"""
        file_name, _ = QFileDialog.getOpenFileName(
            self, 
            "选择M3U8文件",
            filter="M3U8文件 (*.m3u8);;所有文件 (*.*)"
        )
        
        if file_name:
            self.url_entry.setText(file_name)
            
            # 自动提取文件名作为视频名称
            video_name = os.path.splitext(os.path.basename(file_name))[0]
            self.name_entry.setText(video_name)
    
    def select_path(self):
        """选择保存路径"""
        path = QFileDialog.getExistingDirectory(self, "选择保存路径")
        if path:
            self.path_entry.setText(path)
    
    def log_task(self, message):
        """记录任务创建日志"""
        self.task_log.append(f"{time.strftime('%H:%M:%S')} - {message}")
        self.task_log.verticalScrollBar().setValue(self.task_log.verticalScrollBar().maximum())
    
    def log_download(self, message):
        """记录下载日志"""
        self.download_log.append(f"{time.strftime('%H:%M:%S')} - {message}")
        self.download_log.verticalScrollBar().setValue(self.download_log.verticalScrollBar().maximum())
    
    def load_tasks(self):
        """从数据库加载任务列表"""
        self.task_tree.clear()
        
        tasks = self.db.get_all_tasks()
        
        for task in tasks:
            task_id, name, state, total, downloaded = task['id'], task['name'], task['state'], task['totalNum'], task['downloaded']
            state_text = "已完成" if state == 1 else "待下载"
            progress = f"{downloaded}/{total}" if state != 1 else "100%"
            
            item = QTreeWidgetItem([str(task_id), name, state_text, progress])
            self.task_tree.addTopLevelItem(item)
    
    def update_download_status(self):
        """更新下载状态"""
        # 暂时只更新任务列表，实际应用中可能需要更新更详细的状态
        self.load_tasks()
        
    def create_task(self):
        """创建下载任务并解析M3U8文件"""
        # 获取用户输入
        source_type = "url" if self.source_type_group.checkedId() == 1 else "file"
        url_or_path = self.url_entry.text()
        name = self.name_entry.text()
        refer = self.refer_entry.text()
        save_path = self.path_entry.text()
        
        # 验证输入
        if not url_or_path:
            QMessageBox.critical(self, "错误", "请提供M3U8 URL或文件路径")
            return
            
        if not name:
            QMessageBox.critical(self, "错误", "请输入视频名称")
            return
        
        try:
            if source_type == "url":
                parsed_url = urlparse(url_or_path)
                base_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
                if not refer:
                    refer = base_url
                content = download_m3u8(url_or_path, refer)
            else:
                with open(url_or_path, 'r', encoding='utf-8') as f:
                    content = f.read()
                if refer:
                    base_url = refer
                else:
                    base_url = os.path.dirname(url_or_path) or save_path
            
            # 解析M3U8内容
            key_url, segments = parse_m3u8(content, base_url, refer)
            
            # 生成唯一ID
            task_uid = str(self.db.generate_uid())
            
            # 保存到数据库
            task_id = self.db.create_m3u8_task(
                url=url_or_path,
                refer=refer,
                keyUrl=key_url,
                name=name,
                uid=task_uid,
                totalNum=len(segments),
                save_path=save_path
            )
            
            # 保存TS片段
            for order_num, (link, duration) in enumerate(segments):
                self.db.create_ts_segment(
                    order_num=order_num,
                    link=link,
                    second=duration,
                    m3u8Id=task_uid
                )
            
            self.log_task(f"任务创建成功: {name}\n共{len(segments)}个片段")
            
        except Exception as e:
            self.log_task(f"创建任务失败: {str(e)}")
            QMessageBox.critical(self, "错误", f"创建任务失败: {str(e)}")
    
    def get_selected_task(self):
        """获取选中的任务信息"""
        selected = self.task_tree.selectedItems()
        if not selected:
            QMessageBox.information(self, "提示", "请先选择一个任务")
            return None
        
        task_id = int(selected[0].text(0))
        task_info = self.db.get_task(task_id)
        
        if not task_info:
            QMessageBox.critical(self, "错误", f"找不到任务ID: {task_id}")
            return None
            
        return task_info
    
    def start_download(self):
        """开始下载选中任务"""
        task_info = self.get_selected_task()
        if task_info is None:
            return
        
        if task_info['state'] == 1:
            QMessageBox.information(self, "提示", "该任务已完成下载")
            return
        
        # 启动下载 - 使用任务自己的保存路径
        self.download_manager.start_download(
            task_info['id'], 
            task_info['uid'], 
            task_info['save_path'], 
            self.log_download
        )
        
    def pause_download(self):
        """暂停下载选中任务"""
        task_info = self.get_selected_task()
        if task_info is None:
            return
        
        self.download_manager.pause_download(task_info['id'])
        self.log_download(f"任务 {task_info['name']} 已暂停")
        
    def delete_task(self):
        """删除选中的任务"""
        task_info = self.get_selected_task()
        if task_info is None:
            return
        
        # 弹出确认对话框
        confirm = QMessageBox.question(
            self,
            "确认删除",
            f"确定要删除任务 '{task_info['name']}'吗?\n\n这将删除数据库记录和所有相关文件!",
            QMessageBox.Yes | QMessageBox.No
        )
        
        if confirm != QMessageBox.Yes:
            return
        
        # 停止下载任务
        if task_info['id'] in self.download_manager.active_tasks:
            self.download_manager.pause_download(task_info['id'])
        
        # 删除文件
        try:
            self.delete_task_files(task_info)
            self.log_download(f"任务文件已删除: {task_info['name']}")
        except Exception as e:
            self.log_download(f"删除文件失败: {str(e)}")
        
        # 删除数据库记录
        try:
            self.db.delete_task(task_info['uid'])
            self.log_download(f"任务已删除: {task_info['name']}")
        except Exception as e:
            self.log_download(f"删除数据库记录失败: {str(e)}")
        
        # 刷新任务列表
        self.load_tasks()
    
    def delete_task_files(self, task_info):
        """删除任务相关的所有文件"""
        # 获取保存目录 - 使用任务自己的保存路径
        task_dir = os.path.join(task_info['save_path'], task_info['name'])
        
        # 如果目录不存在，直接返回
        if not os.path.exists(task_dir):
            return
            
        # 删除临时TS文件
        for root, _, files in os.walk(task_dir):
            for file in files:
                if file.endswith('.ts') and file.startswith(task_info['uid']):
                    os.remove(os.path.join(root, file))
        
        # 删除合并的MP4文件
        mp4_file = os.path.join(task_dir, f"{task_info['name']}.mp4")
        if os.path.exists(mp4_file):
            os.remove(mp4_file)
        
        # 尝试删除空目录
        try:
            if os.path.exists(task_dir):
                os.rmdir(task_dir)
        except OSError:
            # 目录非空，保留目录
            pass
    
    def closeEvent(self, event):
        """窗口关闭事件处理"""
        # 停止状态更新线程
        self.status_updater.stop()
        self.status_updater.wait()
        
        # 保存数据库并清理资源
        self.download_manager.shutdown()
        self.db.close()
        
        event.accept()

def main():
    import threading
    if threading.current_thread() is not threading.main_thread():
        print("警告：M3U8下载工具必须在主线程中运行")
        # 可以考虑使用信号机制通知主线程启动应用
        return
        
    import sys
    # 检查是否已存在QApplication实例
    app = QApplication.instance()
    if app is None:
        app = QApplication(sys.argv)
        needs_exec = True
    else:
        # 如果已存在QApplication实例，说明是从语音助手中启动的
        # 此时不应该启动新的事件循环，也不应该在窗口关闭时退出应用
        needs_exec = False
    
    window = M3U8DownloaderApp()
    
    # 定义清理函数，但不退出应用程序
    def cleanup():
        if hasattr(window, 'download_manager'):
            window.download_manager.shutdown()
        if hasattr(window, 'db'):
            window.db.close()
        print("M3U8下载工具资源已释放")
    
    # 连接窗口的destroyed信号到清理函数
    window.destroyed.connect(cleanup)
    
    window.show()
    
    # 只有在独立运行时才启动事件循环
    if needs_exec:
        try:
            app.exec_()
        except KeyboardInterrupt:
            print("程序被用户中断")
        except Exception as e:
            print(f"程序异常: {str(e)}")
    
# 主程序入口
if __name__ == "__main__":
    main()